import { Injectable, HttpStatus, HttpException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Mail as MailDTO } from './mail.dto';
import { Mail } from '../entities/mail.entity';
import { MailAccountService } from '../mail-account/mail-account.service';
import type { SendMailOptions, Transporter } from 'nodemailer';
import * as nodemailer from 'nodemailer';
import Imap from 'imap';
import { simpleParser } from 'mailparser';

@Injectable()
export class MailerService {
  constructor(
    @InjectRepository(Mail)
    private mailRepository: Repository<Mail>,
    private accService: MailAccountService,
  ) {}
  async sendMail(mail: MailDTO, req: any) {
    const { account_id, recipient, subject, body } = mail;
    console.log(req.user.id, account_id, recipient, subject, body);
    const account = await this.accService.findOne(account_id);
    console.log(account);

    if (!account) {
      return { message: '账号不存在' };
    }

    const transporter: Transporter = nodemailer.createTransport({
      host: account.smtp_server,
      port: account.smtp_server_port,
      secure: account.ssl_for_smtp_enabled,
      auth: {
        user: account.email_account,
        pass: account.password,
      },
      logger: true,
      debug: true,
    });

    const message: SendMailOptions = {
      from: account.email_account,
      to: recipient,
      subject,
      text: body,
    };

    try {
      const timestamp = new Date();
      const info = await transporter.sendMail(message);

      console.log(nodemailer.getTestMessageUrl(info));

      const mailInfo: Mail = {
        user_id: req.user.id,
        type: 'outbound',
        subject,
        sender: account.email_account,
        recipient,
        content: body,
        send_date: timestamp,
      };
      // 保存到数据库

      const createdMailInfo = this.mailRepository.create(mailInfo);
      await this.mailRepository.save(createdMailInfo);

      transporter.close();

      return { code: 200, message: 'ok' };
    } catch (err) {
      throw new HttpException(err.response, HttpStatus.BAD_REQUEST);
    }
  }

  async findOutbox(req) {
    return await this.mailRepository.find({
      where: { user_id: req.user.id, type: 'outbound' },
      order: { send_date: 'DESC' },
    });
  }

  async findInbox(req) {
    return await this.mailRepository.find({
      where: { user_id: req.user.id, type: 'inbound' },
      order: { send_date: 'DESC' },
    });
  }

  async receiveMail(userId, account_id) {
    console.log(userId, account_id);
    const account = await this.accService.findOne(account_id);
    console.log(account);
    if (!account) {
      return { message: '账号不存在' };
    }

    const inboxList = [];
    if (account.receive_server_type === 'IMAP') {
      const imap = new Imap({
        user: account.email_account,
        password: account.password,
        host: account.receive_server,
        port: account.receive_server_port,
        tls: account.ssl_for_receive_enabled,
      });

      imap.once('ready', () => {
        // 选择邮箱文件夹
        imap.openBox('INBOX', false, (err: Error, mailbox: any) => {
          console.log('mailbox:', mailbox);
          console.log(
            '================================================================================================================================================================================================================================================================================================',
          );
          if (err) throw err;
          // 搜索邮件
          imap.search(['UNSEEN'], (err: Error, results: any) => {
            if (err) throw err;
            const amount = results.length > 5 ? results.length - 5 : 0;
            const last5 = [];
            for (let index = amount; index < results.length; index++) {
              const element = results[index];
              last5[index] = element;
            }
            // 循环处理每封邮件
            let nameIndex = 0;
            last5.forEach((emailId) => {
              const fetch = imap.fetch(emailId, { bodies: '' });
              let createdInMailInfo;
              fetch.on('message', (msg: any, seqno: any) => {
                console.log(
                  'seqno================================================',
                  seqno,
                );
                msg.on('body', (stream: any) => {
                  // 解析邮件内容
                  simpleParser(stream, async (err: Error, parsed: any) => {
                    if (err) throw err;
                    nameIndex += 1;
                    console.log(
                      'parsed================================================',
                      nameIndex,
                      parsed,
                    );

                    const inMail: Mail = {
                      user_id: userId,
                      type: 'inbound',
                      subject: parsed.subject,
                      sender: parsed.from.text,
                      recipient: account.email_account,
                      content: parsed.text,
                      send_date: parsed.date,
                    };
                    inboxList.push(inMail);

                    createdInMailInfo = this.mailRepository.create(inMail);
                    if (!(await this.mailRepository.findOne({ where: inMail })))
                      await this.mailRepository.save(createdInMailInfo);
                  });
                });
              });
            });
          });
        });
      });

      imap.once('error', (err: Error) => {
        throw new HttpException(err.message, HttpStatus.INTERNAL_SERVER_ERROR);
      });

      imap.connect();

      return { message: '开始收件，请稍后回来查看' };
    } else {
      // TODO POP3
      return { message: '暂时不支持该收件协议' };
    }

    return { message: 'ok' };
  }
}
